
#include "clientproxy.h"
#include "gui/command.h"
#include "jansson.h"
#include "log.h"
#include <cstring>
#include <thread>

std::shared_ptr<Session> ClientProxy::mClt = nullptr;
std::map<string, void*> ClientProxy::mObjectsPool;
std::queue<Response> ClientProxy::mResponseQueue;
std::mutex ClientProxy::mMutex;

//==============================================================

ClientProxy::ClientProxy() { }

ClientProxy& ClientProxy::getInstance()
{
    static ClientProxy cp;
    return cp;
}

void ClientProxy::setClient(std::shared_ptr<Session>& clt)
{
    mClt = clt;
}

void ClientProxy::setFillBufferObject(string catag, void* object)
{
    mObjectsPool[catag] = object;
}

void ClientProxy::unSetFillBufferObject(string catag)
{
    mObjectsPool.erase(catag);
}

void ClientProxy::fillResponseQueue(Response r)
{
    std::lock_guard<std::mutex> lck(mMutex);
    mResponseQueue.push(r);
    // ALOGD("Queue front name: %s", mResponseQueue.front().name.c_str());
    // ALOGD("Queue front data: %s", mResponseQueue.front().res.c_str());
    // ALOGD("Queue Size = %lld", mResponseQueue.size());
}

void ClientProxy::send(string type, json_t* json, int& status)
{
    ProxyStatu st;

    if (!mClt) {
        st = ProxyStatu::E_ClientNotInit;
    } else {

        if (mClt->status() == SESSION::CONNECTED) {
            // type转换
            auto it = gCatag.find(type);
            if (it == gCatag.end()) {
                st = ProxyStatu::E_CommandNotFound;
            } else {
                char tp = it->second;

                // json数据dump到string
                const char* str = json_dumps(json, JSON_INDENT(4));
                if (str == NULL) {
                    ALOGE("Need to Send String is NULL!!!");
                    st = ProxyStatu::E_Json_Dump;
                } else {
                    std::vector<char> refStr(str, str + strlen(str));
                    // 发送
                    mClt->doSend(tp, refStr.size(), refStr);
                    st = ProxyStatu::S_KO;
                }
            }
        } else {
            st = ProxyStatu::E_Disconnection;
        }
    }

    status = (int)st;
    json_decref(json);
}

string ClientProxy::recive(string name, int timeout)
{
    string res = "timeout";
    while (timeout) {
        {
            std::lock_guard<std::mutex> lk(mMutex);
            if (!mResponseQueue.empty()) {
                if (mResponseQueue.front().name == name) {
                    res = mResponseQueue.front().res;
                    mResponseQueue.pop();
                    break;
                } else {
                    // 队首不是name指定的命令，则删除队首元素
                    mResponseQueue.pop();
                }
            }
        }
        timeout--;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    return res;
}
